package com.voc.im.controller.account;

import com.alibaba.fastjson.JSON;
import com.voc.im.bean.Account;
import com.voc.im.controller.MainController;
import com.voc.im.manager.StageManager;
import com.voc.im.model.AccountModel;
import com.voc.im.xmpp.IMConnection;
import io.datafx.controller.FXMLController;
import javafx.beans.property.ObjectProperty;
import javafx.concurrent.Service;
import javafx.concurrent.Task;
import javafx.concurrent.Worker;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressBar;
import javafx.scene.control.TextArea;

import javax.annotation.PostConstruct;
import javax.inject.Inject;
import java.util.Map;

@FXMLController("/fxml/account_status.fxml")
public class AccountStatusController {

    private IMConnection imConnection = IMConnection.getInstance();

    @FXML
    private Button btnGoAction;
    @FXML
    private TextArea textHint;
    @FXML
    private Label labelStatus;
    @FXML
    private ProgressBar progressStatus;

    @Inject
    private AccountModel accountModel;

    private Account<Object> objectAccount;

    private Service<Boolean> loginService = new Service<Boolean>() {
        @Override
        protected Task<Boolean> createTask() {
            return new Task<Boolean>() {
                @Override
                protected Boolean call() throws Exception {
                    boolean isSuccess = false;
                    if (objectAccount.getData() instanceof Account.Login) {
                        Account.Login login = (Account.Login) objectAccount.getData();
                        isSuccess = imConnection.connectLogin(login.getUsername(), login.getPassword());
                    }
                    return isSuccess;
                }
            };
        }
    };

    private Service<String> registerService = new Service<String>() {
        @Override
        protected Task<String> createTask() {
            return new Task<String>() {
                @Override
                protected String call() throws Exception {
                    String username = null;
                    if (objectAccount.getData() instanceof Account.Register) {
                        Account.Register register = (Account.Register) objectAccount.getData();
                        username = imConnection.accountCreate(register.getNickname(), register.getPassword());
                    }
                    return username;
                }
            };
        }
    };

    private Service<Boolean> vCardService = new Service<Boolean>() {
        @Override
        protected Task<Boolean> createTask() {
            return new Task<Boolean>() {
                @Override
                protected Boolean call() throws Exception {
                    if (objectAccount.getData() instanceof Account.VCard) {

                    }
                    return imConnection.isUserVCard();
                }
            };
        }
    };

    @PostConstruct
    public void init() throws Exception {

        ObjectProperty<Account<Object>> objectProperty = accountModel.getObjectProperty();
        if (objectProperty == null) {
            return;
        }
        objectAccount = objectProperty.get();
        if (objectAccount == null) {
            return;
        }

        if (objectAccount.getData() instanceof Account.Login) {
            initLogin();
        } else if (objectAccount.getData() instanceof Account.Register) {
            initRegister();
        }

        btnGoAction.setOnAction(this::onAction);
    }

    /**
     * 取消登录/注册点击事件
     */
    private void onAction(ActionEvent event) {
        if (objectAccount.getData() instanceof Account.Login) {
            accountModel.setActionProperty("login");
        } else if (objectAccount.getData() instanceof Account.Register) {
            accountModel.setActionProperty("register");
        }
    }

    /**
     * 发起登录请求
     */
    private void initLogin() {
        loginService.stateProperty().addListener((observable, oldValue, newValue) -> {
            if (newValue == null) {
                return;
            }
            StringBuilder hintStr = new StringBuilder();
            if (newValue == Worker.State.RUNNING) {
                this.visibleStatusProgress();
                hintStr.append("正在登录...");
            } else if (newValue == Worker.State.SUCCEEDED) {
                hintStr.append("登录成功");
            } else if (newValue == Worker.State.FAILED) {
                imConnection.disconnect();
                this.visibleStatusTextArea();
                hintStr.append("登录失败");
            } else if (newValue == Worker.State.CANCELLED) {
                imConnection.disconnect();
            }
            labelStatus.setText(hintStr.toString());
        });
        loginService.exceptionProperty().addListener((observable, oldValue, newValue) -> {
            if (newValue == null) {
                return;
            }
            textHint.setText("失败原因:\n" + newValue.getMessage());
        });
        loginService.valueProperty().addListener((observable, oldValue, newValue) -> {
            if (newValue == null) {
                return;
            }
            if (newValue) {
                try {
                    if (imConnection.isUserVCard()) {
                        StageManager.close(Account2Controller.class);
                        StageManager.stage(MainController.class);
                    } else {
                        Map<String, String> stringMap = imConnection.getAccountAttribute();
                        Account.VCard vCard = new Account.VCard();
                        vCard.setUsername(stringMap.get("username"));
                        vCard.setNickname(stringMap.get("name"));
                        accountModel.setObjectProperty(new Account<>(vCard));
                        accountModel.setActionProperty("vcard");
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            } else {
                this.visibleStatusTextArea();
                labelStatus.setText("登录失败");
                textHint.setText("失败原因:\n未知");
            }
        });
        if (!loginService.isRunning()) {
            loginService.restart();
        }
    }

    /**
     * 发起注册请求
     */
    private void initRegister() {

        registerService.stateProperty().addListener((observable, oldValue, newValue) -> {
            if (newValue == null) {
                return;
            }
            StringBuilder hintStr = new StringBuilder();
            if (newValue == Worker.State.RUNNING) {
                this.visibleStatusProgress();
                hintStr.append("正在注册...");
            } else if (newValue == Worker.State.SUCCEEDED) {
                hintStr.append("注册成功");
            } else if (newValue == Worker.State.FAILED) {
                imConnection.disconnect();
                this.visibleStatusTextArea();
                hintStr.append("注册失败");
            } else if (newValue == Worker.State.CANCELLED) {
                imConnection.disconnect();
            }
            labelStatus.setText(hintStr.toString());
        });
        registerService.exceptionProperty().addListener((observable, oldValue, newValue) -> {
            textHint.setText("失败原因:\n" + newValue.getMessage());
        });
        registerService.valueProperty().addListener((observable, oldValue, newValue) -> {
            if (newValue == null) {
                return;
            }
            this.visibleStatusTextArea();
            textHint.setText(newValue);
        });
        if (!registerService.isRunning()) {
            registerService.restart();
        }
    }


    /**
     * 显示状态页的状态进度条
     */
    private void visibleStatusProgress() {
        progressStatus.setVisible(true);
        textHint.setVisible(false);
    }

    /**
     * 显示状态页的错误信息
     */
    private void visibleStatusTextArea() {
        progressStatus.setVisible(false);
        textHint.setVisible(true);
    }

}
